From 0aa989ae76d0d080eae16b8a4fde59aca1227cc4 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Mon, 30 Apr 2012 15:33:49 -0400 Subject: [PATCH] GtkPlug: fix handling of key events for different layouts GtkPlug directly handles X KeyPress/Release events, instead of using translation in GDK (which expects XI2 events for XI2). When this was done, the handling of the group was stubbed out and never replaced. Export gdk_keymap_x11_group_for_state() and gdk_keymap_x11_is_modifier() so we can fill out the fields correctly. https://bugzilla.gnome.org/show_bug.cgi?id=675167 --- docs/reference/gdk/gdk-docs.sgml | 4 +++ docs/reference/gdk/gdk3-sections.txt | 2 ++ gdk/gdk.symbols | 2 ++ gdk/x11/gdkdevicemanager-core-x11.c | 4 +-- gdk/x11/gdkdevicemanager-xi2.c | 4 +-- gdk/x11/gdkkeys-x11.c | 47 +++++++++++++++++++++++++--- gdk/x11/gdkprivate-x11.h | 4 --- gdk/x11/gdkx11keys.h | 7 +++++ gtk/gtkplug.c | 8 ++--- 9 files changed, 65 insertions(+), 17 deletions(-) diff --git a/docs/reference/gdk/gdk-docs.sgml b/docs/reference/gdk/gdk-docs.sgml index d7c1688788..d5e981e4e1 100644 --- a/docs/reference/gdk/gdk-docs.sgml +++ b/docs/reference/gdk/gdk-docs.sgml @@ -65,6 +65,10 @@ Index of new symbols in 3.4 + + Index of new symbols in 3.6 + + diff --git a/docs/reference/gdk/gdk3-sections.txt b/docs/reference/gdk/gdk3-sections.txt index b46e17e3db..d012c3ca65 100644 --- a/docs/reference/gdk/gdk3-sections.txt +++ b/docs/reference/gdk/gdk3-sections.txt @@ -991,6 +991,8 @@ gdk_x11_grab_server gdk_x11_ungrab_server gdk_x11_cursor_get_xcursor gdk_x11_cursor_get_xdisplay +gdk_x11_keymap_get_group_for_state +gdk_x11_keymap_key_is_modifier gdk_x11_visual_get_xvisual gdk_x11_atom_to_xatom gdk_x11_atom_to_xatom_for_display diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols index 1f1936a802..7b80a3ebfb 100644 --- a/gdk/gdk.symbols +++ b/gdk/gdk.symbols @@ -561,6 +561,8 @@ gdk_x11_get_xatom_name gdk_x11_get_xatom_name_for_display gdk_x11_grab_server gdk_x11_keymap_get_type +gdk_x11_keymap_get_group_for_state +gdk_x11_keymap_key_is_modifier gdk_x11_lookup_xdisplay gdk_x11_register_standard_event_type gdk_x11_screen_get_monitor_output diff --git a/gdk/x11/gdkdevicemanager-core-x11.c b/gdk/x11/gdkdevicemanager-core-x11.c index 38a225cafc..0e49fb76af 100644 --- a/gdk/x11/gdkdevicemanager-core-x11.c +++ b/gdk/x11/gdkdevicemanager-core-x11.c @@ -145,7 +145,7 @@ translate_key_event (GdkDisplay *display, gdk_event_set_device (event, device_manager->core_keyboard); event->key.state = (GdkModifierType) xevent->xkey.state; - event->key.group = _gdk_x11_get_group_for_state (display, xevent->xkey.state); + event->key.group = gdk_x11_keymap_get_group_for_state (keymap, xevent->xkey.state); event->key.hardware_keycode = xevent->xkey.keycode; event->key.keyval = GDK_KEY_VoidSymbol; @@ -161,7 +161,7 @@ translate_key_event (GdkDisplay *display, _gdk_x11_keymap_add_virt_mods (keymap, &state); event->key.state |= state; - event->key.is_modifier = _gdk_x11_keymap_key_is_modifier (keymap, event->key.hardware_keycode); + event->key.is_modifier = gdk_x11_keymap_key_is_modifier (keymap, event->key.hardware_keycode); _gdk_x11_event_translate_keyboard_string (&event->key); diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c index 65ea9dd431..cfbfe6fc0e 100644 --- a/gdk/x11/gdkdevicemanager-xi2.c +++ b/gdk/x11/gdkdevicemanager-xi2.c @@ -1160,10 +1160,10 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator, event->key.time = xev->time; event->key.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group); - event->key.group = _gdk_x11_get_group_for_state (display, event->key.state); + event->key.group = xev->group.effective; event->key.hardware_keycode = xev->detail; - event->key.is_modifier = _gdk_x11_keymap_key_is_modifier (keymap, event->key.hardware_keycode); + event->key.is_modifier = gdk_x11_keymap_key_is_modifier (keymap, event->key.hardware_keycode); device = g_hash_table_lookup (device_manager->id_table, GUINT_TO_POINTER (xev->deviceid)); diff --git a/gdk/x11/gdkkeys-x11.c b/gdk/x11/gdkkeys-x11.c index 0ce16ad324..ac8e401ebf 100644 --- a/gdk/x11/gdkkeys-x11.c +++ b/gdk/x11/gdkkeys-x11.c @@ -1429,11 +1429,30 @@ _gdk_x11_display_manager_keyval_convert_case (GdkDisplayManager *manager, *upper = xupper; } +/** + * gdk_x11_keymap_get_group_for_state: + * @keymap: a #GdkX11Keymap + * @state: raw state returned from X + * + * Extracts the group from the state field sent in an X Key event. + * This is only needed for code processing raw X events, since #GdkEventKey + * directly includes an is_modifier field. + * + * Returns: the index of the active keyboard group for the event + * + * Since: 3.6 + */ gint -_gdk_x11_get_group_for_state (GdkDisplay *display, - GdkModifierType state) +gdk_x11_keymap_get_group_for_state (GdkKeymap *keymap, + guint state) { - GdkX11Display *display_x11 = GDK_X11_DISPLAY (display); + GdkDisplay *display; + GdkX11Display *display_x11; + + g_return_val_if_fail (GDK_IS_X11_KEYMAP (keymap), 0); + + display = keymap->display; + display_x11 = GDK_X11_DISPLAY (display); #ifdef HAVE_XKB if (display_x11->use_xkb) @@ -1498,13 +1517,31 @@ gdk_x11_keymap_add_virtual_modifiers (GdkKeymap *keymap, } } +/** + * gdk_x11_keymap_key_is_modifier: + * @keymap: a #GdkX11Keymap + * @keycode: the hardware keycode from a key event + * + * Determines whether a particular key code represents a key that + * is a modifier. That is, it's a key that normally just affects + * the keyboard state and the behavior of other keys rather than + * producing a direct effect itself. This is only needed for code + * processing raw X events, since #GdkEventKey directly includes + * an is_modifier field. + * + * Returns: %TRUE if the hardware keycode is a modifier key + * + * Since: 3.6 + */ gboolean -_gdk_x11_keymap_key_is_modifier (GdkKeymap *keymap, - guint keycode) +gdk_x11_keymap_key_is_modifier (GdkKeymap *keymap, + guint keycode) { GdkX11Keymap *keymap_x11 = GDK_X11_KEYMAP (keymap); gint i; + g_return_val_if_fail (GDK_IS_X11_KEYMAP (keymap), FALSE); + update_keyrange (keymap_x11); if (keycode < keymap_x11->min_keycode || keycode > keymap_x11->max_keycode) diff --git a/gdk/x11/gdkprivate-x11.h b/gdk/x11/gdkprivate-x11.h index b5f68b2645..80380c0270 100644 --- a/gdk/x11/gdkprivate-x11.h +++ b/gdk/x11/gdkprivate-x11.h @@ -155,12 +155,8 @@ gboolean _gdk_x11_moveresize_configure_done (GdkDisplay *display, void _gdk_x11_keymap_state_changed (GdkDisplay *display, XEvent *event); void _gdk_x11_keymap_keys_changed (GdkDisplay *display); -gint _gdk_x11_get_group_for_state (GdkDisplay *display, - GdkModifierType state); void _gdk_x11_keymap_add_virt_mods (GdkKeymap *keymap, GdkModifierType *modifiers); -gboolean _gdk_x11_keymap_key_is_modifier (GdkKeymap *keymap, - guint keycode); void _gdk_x11_windowing_init (void); diff --git a/gdk/x11/gdkx11keys.h b/gdk/x11/gdkx11keys.h index dea8c73f06..a417e33cf2 100644 --- a/gdk/x11/gdkx11keys.h +++ b/gdk/x11/gdkx11keys.h @@ -42,6 +42,13 @@ typedef struct _GdkX11KeymapClass GdkX11KeymapClass; GType gdk_x11_keymap_get_type (void); +GDK_AVAILABLE_IN_3_6 +gint gdk_x11_keymap_get_group_for_state (GdkKeymap *keymap, + guint state); + +GDK_AVAILABLE_IN_3_6 +gboolean gdk_x11_keymap_key_is_modifier (GdkKeymap *keymap, + guint keycode); G_END_DECLS #endif /* __GDK_X11_KEYMAP_H__ */ diff --git a/gtk/gtkplug.c b/gtk/gtkplug.c index 048ef2915e..0b9f028b3f 100644 --- a/gtk/gtkplug.c +++ b/gtk/gtkplug.c @@ -982,6 +982,10 @@ gtk_plug_filter_func (GdkXEvent *gdk_xevent, gdk_event_set_device (event, keyboard); keymap = gdk_keymap_get_for_display (display); + + event->key.group = gdk_x11_keymap_get_group_for_state (keymap, xevent->xkey.state); + event->key.is_modifier = gdk_x11_keymap_key_is_modifier (keymap, event->key.hardware_keycode); + gdk_keymap_translate_keyboard_state (keymap, event->key.hardware_keycode, event->key.state, @@ -996,10 +1000,6 @@ gtk_plug_filter_func (GdkXEvent *gdk_xevent, event->key.length = 0; event->key.string = g_strdup (""); - /* FIXME: These should be filled in properly */ - event->key.group = 0; - event->key.is_modifier = FALSE; - return_val = GDK_FILTER_TRANSLATE; } } -- 2.30.2